/**
 * @file   SetPropertyValueRequestPacket.cpp
 * @author Djuro Drljaca (djurodrljaca@gmail.com)
 * @date   2014-04-23
 * @brief  DON packet object: Set Property Value Request
 *
 * Copyright 2014  Djuro Drljaca (djurodrljaca@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <DON/Core/Packet/SetPropertyValueRequestPacket.h>
#include <DON/Core/DataType/UInt16.h>
#include <QtCore/QByteArray>

using namespace DON::Core::Packet;
using namespace DON::Core::DataType;

class SetPropertyValueRequestPacket::Private
{
public:
    Private()
        : propertyId(0u),
          propertyValue(NULL)
    { }

    ~Private()
    {
        delete propertyValue;
    }

    quint16 propertyId;
    const AbstractDataType *propertyValue;
};

SetPropertyValueRequestPacket::SetPropertyValueRequestPacket()
    : AbstractPacket(),
      d(new Private())
{
    setPacketType(PacketType_SetPropertyValueRequest);
}

SetPropertyValueRequestPacket::SetPropertyValueRequestPacket(const quint16 source,
                                                             const quint16 destination,
                                                             const quint16 sequence,
                                                             const quint16 propertyId,
                                                             const AbstractDataType *propertyValue)
    : AbstractPacket(source,
                     destination,
                     PacketType_SetPropertyValueRequest,
                     sequence),
      d(new Private())
{
    d->propertyId = propertyId;

    if (propertyValue != NULL)
    {
        d->propertyValue = propertyValue->clone();
    }
}

SetPropertyValueRequestPacket::SetPropertyValueRequestPacket(
        const SetPropertyValueRequestPacket &other)
    : AbstractPacket(other),
      d(new Private())
{
    d->propertyId = other.d->propertyId;

    if (other.d->propertyValue != NULL)
    {
        d->propertyValue = other.d->propertyValue->clone();
    }
}

SetPropertyValueRequestPacket::~SetPropertyValueRequestPacket()
{
    delete d;
}

SetPropertyValueRequestPacket & SetPropertyValueRequestPacket::operator=(
        const SetPropertyValueRequestPacket &other)
{
    AbstractPacket::operator=(other);

    d->propertyId = other.d->propertyId;

    setPropertyValue(other.d->propertyValue);

    return *this;
}

bool SetPropertyValueRequestPacket::isValid() const
{
    bool valid = false;

    if (d->propertyValue != NULL)
    {
       if (isDataTypeValid(d->propertyValue->getDataType()))
       {
           valid = true;
       }
    }

    return valid;
}

quint16 SetPropertyValueRequestPacket::getPropertyId() const
{
    return d->propertyId;
}

void SetPropertyValueRequestPacket::setPropertyId(const quint16 propertyId)
{
    d->propertyId = propertyId;
}

const AbstractDataType * SetPropertyValueRequestPacket::getPropertyValue() const
{
    return d->propertyValue;
}

void SetPropertyValueRequestPacket::setPropertyValue(const AbstractDataType *propertyValue)
{
    delete d->propertyValue;
    d->propertyValue = NULL;

    if (propertyValue != NULL)
    {
        d->propertyValue = propertyValue->clone();
    }
}

QList<QByteArray> SetPropertyValueRequestPacket::getPayloadDataItems(bool *ok) const
{
    QList<QByteArray> payloadDataItems;
    bool success = false;

    if (isValid())
    {
        success = true;

        // Property ID
        payloadDataItems.append(UInt16::toBinary(d->propertyId));

        // Property Value
        const char dataTypeData = fromDataTypeToBinary(d->propertyValue->getDataType());
        const QByteArray valueData = d->propertyValue->toBinary();

        if (valueData.isEmpty())
        {
            // Error
            payloadDataItems.clear();
            success = false;
        }
        else
        {
            QByteArray propertyValueData;
            propertyValueData.append(dataTypeData);
            propertyValueData.append(valueData);

            payloadDataItems.append(propertyValueData);
        }
    }

    if (ok != NULL)
    {
        *ok = success;
    }

    return payloadDataItems;
}
